package chapter10;

import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.behaviors.mouse.*;
import com.sun.j3d.utils.behaviors.keyboard.*;

public class Ex5 extends Applet {
  public static void main(String[] args) {
    new MainFrame(new Ex5(), 640, 480);
  }

  public void init() {
    // create canvas
    GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
    Canvas3D cv = new Canvas3D(gc);
    setLayout(new BorderLayout());
    add(cv, BorderLayout.CENTER);
    BranchGroup bg = createSceneGraph();
    bg.compile();
    SimpleUniverse su = new SimpleUniverse(cv);
    su.getViewingPlatform().setNominalViewingTransform();
    su.addBranchGraph(bg);
  }

  private BranchGroup createSceneGraph() {
    BranchGroup root = new BranchGroup();
    TransformGroup spin = new TransformGroup();
    spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    spin.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    root.addChild(spin);
    // clock face
    Appearance apFace = new Appearance();
    Material matFace = new Material();
    matFace.setAmbientColor(new Color3f(0f,0f,0f));
    matFace.setDiffuseColor(new Color3f(0.15f,0.15f,0.25f));
    apFace.setMaterial(matFace);
    Cylinder face = new Cylinder(0.6f, 0.01f, Cylinder.GENERATE_NORMALS, 50, 2, apFace);
    Transform3D tr = new Transform3D();
    tr.rotX(Math.PI/2);
    tr.setTranslation(new Vector3d(0,0,-0.01));
    TransformGroup tg = new TransformGroup(tr);
    tg.addChild(face);
    spin.addChild(tg);
    // text
    Appearance ap = new Appearance();
    ap.setMaterial(new Material());
    Font3D font = new Font3D(new Font("SansSerif", Font.PLAIN, 1),
                             new FontExtrusion());
    Text3D text = new Text3D(font, "Java 3D Clock");
    text.setCapability(Text3D.ALLOW_STRING_WRITE);
    Shape3D shape = new Shape3D(text, ap);
    //transformation
    tr = new Transform3D();
    tr.setScale(0.25);
    tr.setTranslation(new Vector3f(-0.45f, -0.1f, 0f));
    tg = new TransformGroup(tr);
    spin.addChild(tg);
    tg.addChild(shape);
    // Behavior node
    Behavior behav = new ClockBehavior(text);
    BoundingSphere bounds = new BoundingSphere();
    behav.setSchedulingBounds(bounds);
    root.addChild(behav);
    // mouse rotation
    MouseRotate rotator = new MouseRotate(spin);
    rotator.setSchedulingBounds(bounds);
    spin.addChild(rotator);
    // mouse translation
    MouseTranslate translator = new MouseTranslate(spin);
    translator.setSchedulingBounds(bounds);
    spin.addChild(translator);
    // mouse zoom
    MouseZoom zoom = new MouseZoom(spin);
    zoom.setSchedulingBounds(bounds);
    spin.addChild(zoom);
    // key behavior
    KeyNavigatorBehavior behavior = new KeyNavigatorBehavior(spin);
    behavior.setSchedulingBounds(bounds);
    spin.addChild(behavior);
    //light
    AmbientLight light = new AmbientLight(true, new Color3f(Color.blue));
    light.setInfluencingBounds(bounds);
    root.addChild(light);
    PointLight ptlight = new PointLight(new Color3f(Color.white), new Point3f(0.7f,0.7f,2f), new Point3f(1f,0f,0f));
    ptlight.setInfluencingBounds(bounds);
    root.addChild(ptlight);
    //background
    Background background = new Background(0.7f, 0.7f, 0.7f);
    background.setApplicationBounds(bounds);
    root.addChild(background);
    return root;
  }
}

